package top.juc.plugin.idea.openfeignx.provider;

import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider;
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import org.apache.commons.lang3.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import top.juc.plugin.idea.openfeignx.annotation.Annotation;
import top.juc.plugin.idea.openfeignx.util.CacheUtils;
import top.juc.plugin.idea.openfeignx.util.JavaUtils;
import top.juc.plugin.idea.openfeignx.util.SpringMvcUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import static top.juc.plugin.idea.openfeignx.util.Icons.IMAGES_CONTROLLER_SVG;

/**
 * The type Mapper line marker provider.
 *
 * @author yanglin
 */
public class FeignLineMarkerProvider extends RelatedItemLineMarkerProvider {

    @Override
    protected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection<? super RelatedItemLineMarkerInfo<?>> result) {
        if (!(element instanceof PsiClass)) {
            return;
        }
        // class方法的类包含 @FeignClient 注解
        PsiClass clazz = (PsiClass) element;
        if (!isTargetClass(clazz)) {
            return;
        }


        CacheUtils.clearClass(element.getProject(), Annotation.FEIGN_CLIENT, clazz);
        // 扫描找到所有@RestController的方法
        ConcurrentHashMap<String, PsiMethod> feignPathMap = SpringMvcUtils.getFeignPath(Collections.singletonList(clazz));
        feignPathMap.forEach((key, method) -> {
            CacheUtils.setMethod(element.getProject(), Annotation.FEIGN_CLIENT, key, method);
            PsiMethod psiMethod = CacheUtils.getMethod(element.getProject(), Annotation.REST_CONTROLLER, key);
            if(ObjectUtils.isEmpty(psiMethod)){
                return;
            }




            NavigationGutterIconBuilder<PsiElement> builder =
                NavigationGutterIconBuilder.create(IconLoader.getIcon(IMAGES_CONTROLLER_SVG, this.getClass()))
                    .setAlignment(GutterIconRenderer.Alignment.CENTER)
                    .setTarget(psiMethod)
                    .setTooltipTitle("Controller - " + Optional.ofNullable(psiMethod.getContainingClass()).map(PsiClass::getQualifiedName).orElse("") + "#" + psiMethod.getName());
            result.add(builder.createLineMarkerInfo(method.getNameIdentifier()));
        });
    }

    private boolean isTargetClass(PsiClass clazz) {
        return JavaUtils.isAnnotationPresent(clazz, Annotation.FEIGN_CLIENT);
    }
}
